package hsl.study.v2;


import net.bytebuddy.ByteBuddy;
import net.bytebuddy.implementation.MethodDelegation;
import net.bytebuddy.implementation.bind.annotation.AllArguments;
import net.bytebuddy.implementation.bind.annotation.Origin;
import net.bytebuddy.implementation.bind.annotation.RuntimeType;
import net.bytebuddy.implementation.bind.annotation.SuperCall;
import net.bytebuddy.matcher.ElementMatchers;
import org.aopalliance.intercept.Interceptor;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.concurrent.Callable;

/**
 * @author HSL
 * @version 1.0
 * @data 2025/11/17 11:01
 * @desc todo
 */

public class ByteBuddyProxyFactory {
    // 创建被代理的真实对象
    private final Object target;

    // 构造方法注入
    public ByteBuddyProxyFactory(Object target) {
        this.target = target;
    }

    // 创建代理对象
    public Object getProxyInstance() {

        Class<?> targetClass = target.getClass();
        Class<?> proxyClass = new ByteBuddy()
                .subclass(targetClass)
                .method(ElementMatchers.any())
                .intercept(MethodDelegation.to(new Interceptor(target)))
                .make()
                .load(targetClass.getClassLoader())
                .getLoaded();

        try {
            return proxyClass.getDeclaredConstructor().newInstance();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 拦截器类
     */
    public static class Interceptor {
        private final Object target;

        public Interceptor(Object target) {
            this.target = target;
        }

        @RuntimeType
        public Object intercept(@Origin Method method,
                                @AllArguments Object[] args,
                                @SuperCall Callable<?> superMethod) throws Exception
        {

            System.out.println("【ByteBuddy 代理前】方法：" + method.getName());

            Object result = superMethod.call();  // 等价于 CGLIB 的 proxy.invokeSuper

            System.out.println("【ByteBuddy 代理后】方法执行完毕");

            return result;
        }
    }

}
